package com.gw.vip.server.platform.vipcenter;

import com.alibaba.fastjson.JSONObject;
import com.gw.vip.common.exception.ExceptionEnums;
import com.gw.vip.common.exception.ServiceException;
import com.gw.vip.server.bo.IssuInfo;
import com.gw.vip.server.constants.SysArgKey;
import com.gw.vip.server.platform.vipcenter.dto.VipCenterIssuInfoDto;
import com.gw.vip.server.platform.vipcenter.dto.VipCenterSetMailSenderInfoDto;
import com.gw.vip.server.platform.vipcenter.dto.VipCenterUserInfoByCodeDto;
import com.gw.vip.server.platform.vipcenter.vo.VipCenterIssuInfoVo;
import com.gw.vip.server.platform.vipcenter.vo.VipCenterUserInfoByCodeVo;
import com.gw.vip.server.service.dao_service.SysArgService;
import com.gw.vip.server.sign.SignService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @author GW
 * @description
 * @since 2022-04-25
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class VipCenterService {

    @Value("${vipCenter.domain}")
    private String domain;

    @Value("${vipCenter.uri.userInfoByCode}")
    private String userInfoByCodeUri;

    @Value("${vipCenter.uri.issuInfo}")
    private String issuInfoUri;

    @Value("${vipCenter.uri.setMailSenderInfo}")
    private String setMailSenderInfoUri;

    private final RestTemplate restTemplate;
    private final SignService signService;
    private final SysArgService sysArgService;

    public VipCenterUserInfoByCodeVo userInfoByCode(VipCenterUserInfoByCodeDto dto){
        JSONObject request = (JSONObject) JSONObject.toJSON(dto);
        JSONObject response = this.post(userInfoByCodeUri, request, "根据code获取用户信息");
        return response.toJavaObject(VipCenterUserInfoByCodeVo.class);
    }

    public VipCenterIssuInfoVo issuInfo(VipCenterIssuInfoDto dto){
        JSONObject request = (JSONObject) JSONObject.toJSON(dto);
        JSONObject response = this.noSignPost(issuInfoUri, request, "获取发行机构信息");
        return response.toJavaObject(VipCenterIssuInfoVo.class);
    }

    public void setMailSenderInfo(VipCenterSetMailSenderInfoDto dto){
        JSONObject request = (JSONObject) JSONObject.toJSON(dto);
        this.noSignPost(setMailSenderInfoUri, request, "设置邮件发送者");
    }

    //---------------------------------- 辅助函数 ------------------------------------//

    private JSONObject post(String uri, JSONObject request, String actionName){
        //统一签名
        request.put("signType", "SHA256");
        IssuInfo issuInfo = sysArgService.getObject(SysArgKey.ISSU_INFO, IssuInfo.class);
        if (issuInfo==null){
            log.error("发行机构不存在！");
            throw new ServiceException("发行机构不存在!");
        }
        String sign = signService.getSign(request, issuInfo.getAccessKey());
        request.put("sign", sign);

        log.info("向vip-center发起【{}】请求----url【{}】", actionName, domain+uri);
        log.info("向vip-center发起【{}】请求----参数【{}】", actionName, request);
        JSONObject response;
        try{
            response = restTemplate.postForObject(domain+uri, request, JSONObject.class);
        }catch (Exception e){
            log.error("", e);
            log.error("请求异常，视为结果未知！");
            throw new ServiceException(ExceptionEnums.OTHER_SYSTEM_ERROR, e.getMessage());
        }

        if (response==null){
            log.error("返回信息为空，视为结果未知！");
            throw new ServiceException(ExceptionEnums.OTHER_SYSTEM_ERROR);
        }
        log.info("向vip-center发起【{}】请求----返回【{}】", actionName, response);

        String resultCode=response.getString(VipCenterKey.RESULT_CODE);
        if (StringUtils.isBlank(resultCode)){
            log.error("请求vip中心返回错误，没有返回码!");
            throw new ServiceException(ExceptionEnums.OTHER_SYSTEM_ERROR, "没有返回码");
        }
        String resultMsg=response.getString(VipCenterKey.RESULT_MSG);

        if (!resultCode.equals(VipCenterKey.SUCCESS_CODE)){
            //请求失败
            throw new ServiceException(resultCode, resultMsg);
        }

        return response.getJSONObject("data");
    }

    /**
     * 不用验签的交易
     * @param uri
     * @param request
     * @param actionName
     * @return
     */
    private JSONObject noSignPost(String uri, JSONObject request, String actionName){
        log.info("向vip-center发起【{}】请求----url【{}】", actionName, domain+uri);
        log.info("向vip-center发起【{}】请求----参数【{}】", actionName, request);
        JSONObject response;
        try{
            response = restTemplate.postForObject(domain+uri, request, JSONObject.class);
        }catch (Exception e){
            log.error("", e);
            log.error("请求异常，视为结果未知！");
            throw new ServiceException(ExceptionEnums.OTHER_SYSTEM_ERROR, e.getMessage());
        }

        if (response==null){
            log.error("返回信息为空，视为结果未知！");
            throw new ServiceException(ExceptionEnums.OTHER_SYSTEM_ERROR);
        }
        log.info("向vip-center发起【{}】请求----返回【{}】", actionName, response);

        String resultCode=response.getString(VipCenterKey.RESULT_CODE);
        if (StringUtils.isBlank(resultCode)){
            log.error("请求vip中心返回错误，没有返回码!");
            throw new ServiceException(ExceptionEnums.OTHER_SYSTEM_ERROR, "没有返回码");
        }
        String resultMsg=response.getString(VipCenterKey.RESULT_MSG);

        if (!resultCode.equals(VipCenterKey.SUCCESS_CODE)){
            //请求失败
            throw new ServiceException(resultCode, resultMsg);
        }

        return response.getJSONObject("data");
    }
}
